package yxk.task.trainingProgram;

import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson.JSONArray;
import com.apusic.aas.util.codec.binary.Base64;
import com.grapecity.documents.excel.Q;
import kd.bos.context.RequestContext;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.exception.KDException;
import kd.bos.fileservice.FileItem;
import kd.bos.fileservice.FileService;
import kd.bos.fileservice.FileServiceFactory;
import kd.bos.logging.Log;
import kd.bos.logging.LogFactory;
import kd.bos.orm.query.QCP;
import kd.bos.orm.query.QFilter;
import kd.bos.schedule.api.MessageHandler;
import kd.bos.schedule.executor.AbstractTask;
import kd.bos.servicehelper.AttDto;
import kd.bos.servicehelper.AttachmentServiceHelper;
import kd.bos.servicehelper.BusinessDataServiceHelper;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.InputStream;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.*;

import com.alibaba.fastjson.JSONObject;
import kd.bos.servicehelper.operation.DeleteServiceHelper;
import kd.bos.servicehelper.operation.SaveServiceHelper;

/**
 * 【需求描述】在培训系统中培训项目，同步到人员档案中，在人员档案可以及时查看，关于内部培训存在培训证书附件也需要通过接口传递（有下载地址）
 */
public class TrainingProgramAll extends AbstractTask {
    private static final Log LOG = LogFactory.getLog(TrainingProgramAll.class);
    @Override
    public MessageHandler getMessageHandle() {
        return super.getMessageHandle();
    }

    /**
     * 1.获取所有项目ID
     * 2.根据获取所有人员培训项目信息
     * @param requestContext
     * @param map
     * @throws KDException
     */
    @Override
    public void execute(RequestContext requestContext, Map<String, Object> map) throws KDException {
        //删除同步过来的所有培训项目信息
        QFilter qFilter = new QFilter("description", QCP.equals,"来源：培训系统");
        DynamicObject[] delhrpi_emptrainfile = BusinessDataServiceHelper.load("hrpi_emptrainfile", "id", qFilter.toArray());
        //清空附件
//        for (int i = 0; i < delhrpi_emptrainfile.length; i++) {
//            AttachmentServiceHelper.remove("hrpi_emptrainfile",delhrpi_emptrainfile[i].getString("id"));
//        }
        DeleteServiceHelper.delete("hrpi_emptrainfile", qFilter.toArray());
        String testPerson = "";
        //1.获取所有的项目ID
        Map<String, String> stringStringMap = GetToken();
        String access_token = stringStringMap.get("access_token");
        String enterprise_id = stringStringMap.get("enterprise_id");
        //获取调用项目列表地址
        qFilter = new QFilter("number", QCP.equals,"study_projects_fast");
        qFilter.and(new QFilter("enable", QCP.equals,"1"));
        DynamicObject[] nwg5_configurations = BusinessDataServiceHelper.load("nwg5_configuration", "nwg5_url", qFilter.toArray());
        String study_projects_fast_url = nwg5_configurations[0].getString("nwg5_url");
        LOG.info("项目列表地址请求地址："+study_projects_fast_url);
        Set<String> set = new HashSet<String>();
        for (int i = 1; i < 100; i++) {
            String study_projects_fast_body = HttpRequest.get(study_projects_fast_url+"?enterprise-id="+enterprise_id+"&begin_time=1000-04-17&end_time=2999-04-30&page_number="+i+"&page_size=1000")
                    .header("o-access-token", access_token)
                    .timeout(180000)
                    .execute()
                    .body();
            LOG.info("项目列表获接口取的值："+study_projects_fast_body);
            JSONObject jsonObject = JSONObject.parseObject(study_projects_fast_body);
            JSONObject data = jsonObject.getJSONObject("data");
            JSONArray list = data.getJSONArray("list");

            for (int x = 0;x<list.size();x++){
                set.add(list.getJSONObject(x).getString("course_id"));
            }
            if("false".equals(data.getString("has_next_page"))){
                break;
            }
        }
        qFilter = new QFilter("number", QCP.equals,"viewStuPro");
        qFilter.and(new QFilter("enable", QCP.equals,"1"));
        nwg5_configurations = BusinessDataServiceHelper.load("nwg5_configuration", "nwg5_url", qFilter.toArray());
        String viewStuProUrl = nwg5_configurations[0].getString("nwg5_url");
        //2.根据获取所有人员培训项目信息
        DynamicObject[] hrpi_empproexps = new DynamicObject[]{};
        for(String cus_id:set){
            n:for (int i = 1; i < 1000; i++) {
                String study_projects_fast_body = HttpRequest.get(viewStuProUrl+"/"+enterprise_id+"/study_projects/"+cus_id+"/user_monitors?page_number="+i+"&page_size=1000")
                        .header("o-access-token", access_token)
                        .timeout(180000)
                        .execute()
                        .body();
                //培训课程
                String title = JSONObject.parseObject(study_projects_fast_body).getJSONObject("data").getJSONObject("study_project").getString("title");
                //费用预算
                String budget = String.valueOf(JSONObject.parseObject(study_projects_fast_body).getJSONObject("data").getJSONObject("study_project").getBigDecimal("budget"));
                //培训证书
                String certificate_name = String.valueOf(JSONObject.parseObject(study_projects_fast_body).getJSONObject("data").getJSONObject("study_project").getString("certificate_name"));
                JSONArray jsonArray = JSONObject.parseObject(study_projects_fast_body).getJSONObject("data").getJSONObject("monitor_list").getJSONArray("list");
                nn:for (int j = 0; j < jsonArray.size(); j++) {
                    Date task_begin_time = jsonArray.getJSONObject(j).getDate("task_begin_time");//任务开始时间
                    Date task_end_time = jsonArray.getJSONObject(j).getDate("task_end_time");//任务结束时间
                    BigDecimal study_duration = jsonArray.getJSONObject(j).getBigDecimal("study_duration");//培训课时
                    String jobnumber = jsonArray.getJSONObject(j).getString("jobnumber");//员工编号
                    testPerson+=jobnumber+",";
                    //是否存在该员工
                    QFilter personQF = new QFilter("number",QCP.equals,jobnumber);
                    DynamicObject[] load = BusinessDataServiceHelper.load("hrpi_person", "id", personQF.toArray());
                    if(load.length == 0){
                        continue  nn;
                    }
                    String personId = load[0].getString("id");
                    DynamicObject hrpi_empproexp = BusinessDataServiceHelper.newDynamicObject("hrpi_emptrainfile");
                    hrpi_empproexp.set("person",personId);//人员
                    hrpi_empproexp.set("startdate",task_begin_time);//开始日期
                    hrpi_empproexp.set("enddate",task_end_time);//结束日期
                    hrpi_empproexp.set("name",title);//培训课程
                    hrpi_empproexp.set("classhour",study_duration);//培训课时
                    hrpi_empproexp.set("cost",budget);//培训费用
                    hrpi_empproexp.set("trainingcertificate",certificate_name);//培训证书
                    hrpi_empproexp.set("iscurrentversion","1");//是否当前版本
                    hrpi_empproexp.set("datastatus","1");//数据是否生效
                    hrpi_empproexp.set("initstatus","2");//初始化状态
                    hrpi_empproexp.set("sourcevid",(new Date()).getTime()+j);//初始化状态
                    //设置默认值
                    hrpi_empproexp.set("description","来源：培训系统");//培训课时
                    QFilter hbss_traintypeF = new QFilter("number",QCP.equals,"1010_S");
                    DynamicObject[] hbss_traintypes = BusinessDataServiceHelper.load("hbss_traintype", "id", hbss_traintypeF.toArray());
                    if(hbss_traintypes.length>0){
                        hrpi_empproexp.set("traintype",hbss_traintypes[0].getLong("id"));//培训类别
                    }
                    SaveServiceHelper.save(new DynamicObject[]{hrpi_empproexp});
                }
                //判断是否有下一页
                if("false".equals(JSONObject.parseObject(study_projects_fast_body).getJSONObject("data").getJSONObject("monitor_list").getString("has_next_page"))){
                    break n;
                }
            }
        }
        LOG.info("涉及修改的人员信息:"+testPerson);
        //附件绑定



    }
    //获取access_token
    public  Map<String,String> GetToken(){
        Map<String,String> map = new HashMap();
        Long timestamp = System.currentTimeMillis();
        QFilter qFilter = new QFilter("number", QCP.equals,"TrainingProgram");
        qFilter.and(new QFilter("enable", QCP.equals,"1"));
        DynamicObject[] nwg5_configurations = BusinessDataServiceHelper.load("nwg5_configuration", "nwg5_user,nwg5_password,nwg5_tokenurl,nwg5_url", qFilter.toArray());
        String apiKey = nwg5_configurations[0].getString("nwg5_user");
        String apiSecret = nwg5_configurations[0].getString("nwg5_password");
        String nwg5_url = nwg5_configurations[0].getString("nwg5_url");
        String seed = String.format(timestamp+"\n"+apiKey);
        String computedSignature = null;
        try {
            computedSignature = getSignature(seed, apiSecret);
        } catch (Exception e) {
            LOG.info("获取computedSignature出错:"+e.getMessage());
            throw new RuntimeException(e);
        }
        LOG.info("api_key:"+apiKey+",api_secret:"+apiSecret);
        JSONObject param=new JSONObject();
        param.put("signature",computedSignature);
        param.put("api_key",apiKey);
        param.put("api_secret",apiSecret);
        param.put("timestamp",timestamp);
        String results = HttpRequest.post(nwg5_url)
                .header("Content-Type", "application/json;charset=utf-8")
                .body(param.toString())
                .timeout(180000)
                .execute().body();
        LOG.info("获取token结果如下，返回参数results:"+results);
        //获取结果，得到access_token，返回报文如下
        /**
         * {
         *   "code": "0",
         *   "data": {
         *     "access_token": "24d0d0d4f3344e2cbf5317f630b4868e",
         *     "expire_at": 1695137699259
         *   },
         *   "request_id": "9695d2fb0fec4feb8fa90532c8a17b49",
         *   "success": "true",
         *   "message": "success"
         * }
         */
        JSONObject resultsJson = JSONObject.parseObject(results);
        JSONObject dataJson = resultsJson.getJSONObject("data");
        String access_token = dataJson.getString("access_token");
        map.put("access_token",access_token);
        map.put("enterprise_id",nwg5_configurations[0].getString("nwg5_tokenurl"));
        LOG.info("返回参数access_token:"+access_token+",Enterprise_id:"+nwg5_configurations[0].getString("nwg5_tokenurl"));
        return map;
    }

    public static String getSignature(String content, String secret) throws NoSuchAlgorithmException, InvalidKeyException {
        Mac sha256HMAC = Mac.getInstance("HmacSHA256");
        SecretKeySpec secretKey = new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
        sha256HMAC.init(secretKey);
        byte[] hash = sha256HMAC.doFinal(content.getBytes(StandardCharsets.UTF_8));
        String encodeStr = Base64.encodeBase64String(hash);
        return encodeStr;
    }


    //上传附件
    public static void setAttachment(InputStream fileStream, DynamicObject srcbillo, String name, String attname) throws Exception{
        if(srcbillo==null){
            return;
        }
        DynamicObject srcbill = BusinessDataServiceHelper.loadSingle(srcbillo.getPkValue(), srcbillo.getDynamicObjectType().getName());
        Map<String,Object> params=new HashMap();
        params.put("formNumber",srcbill.getDynamicObjectType().getName());// 目标单据标识
        params.put("billPkId",srcbill.getPkValue());//目标单据PkId
        Map<String,Object> map=new HashMap();
        List<AttDto> list=new ArrayList<>();

        FileService fs= FileServiceFactory.getAttachmentFileService();
        String path = "/"+srcbill.getDynamicObjectType().getName()+"/attachmentpanel/"+name;
        int size=fileStream.available();
        LOG.info("size:"+size);
        FileItem fi = new FileItem(name,path,fileStream);

        fi.setCreateNewFileWhenExists(true);
        String paths= fs.upload(fi);
        //获取实际存储路径
        String realPath = FileServiceFactory.getAttachmentFileService().getFileServiceExt().getRealPath(paths);
        LOG.info("==realPath=="+realPath);
        LOG.info("path:"+paths);
        AttacUpdate(srcbillo,name,realPath,size,attname);
    }

    public static void AttacUpdate(DynamicObject pkid,String fileName,String uploadPath,int size,String attname){
        Map uploadFileMap = new HashMap();
        uploadFileMap.put("entityNum", pkid.getDynamicObjectType().getName());
        uploadFileMap.put("billPkId", pkid.toString());
        uploadFileMap.put("lastModified", new Date().getTime());

        StringBuffer uid = new StringBuffer();
        long time = new Date().getTime();
        uid.append("rc-upload-");
        uid.append(time);
        uid.append("-");
        uid.append("1");
        uploadFileMap.put("uid", uid.toString());
        uploadFileMap.put("name", fileName);
        uploadFileMap.put("url", uploadPath);
        uploadFileMap.put("size", size);
        uploadFileMap.put("status", "success");

        List<Map<String, Object>> attachments = new ArrayList<>();
        attachments.add(uploadFileMap);

        AttachmentServiceHelper.upload(pkid.getDynamicObjectType().getName(), pkid.getPkValue(), attname, attachments);

    }


}
